//
//  comBlueboxmoonPhoneHover.m
//  snomPhone
//
//  Created by Daniel Hazelbaker on 11/30/10.
//  Copyright 2010 High Desert Church. All rights reserved.
//

#import "comBlueboxmoonPhoneHover.h"
#import "BMSnomPhone.h"
#import "SSHover.h"
#import "SSCall.h"


@implementation comBlueboxmoonPhoneHover


//
// Set the default preferences.
//
+ (void)setDefaultPreferences
{
    BMPreferences *dict = [BMSnomPhone preferences];
    
    
    if ([dict valueForKey:kPopupIncomingEnabledKey] == nil)
	[dict setValue:[NSNumber numberWithBool:YES] forKey:kPopupIncomingEnabledKey];
    
    if ([dict valueForKey:kPopupOutgoingEnabledKey] == nil)
	[dict setValue:[NSNumber numberWithBool:NO] forKey:kPopupOutgoingEnabledKey];

    if ([dict valueForKey:kPopupDurationKey] == nil)
	[dict setValue:[NSNumber numberWithInt:7] forKey:kPopupDurationKey];
}


//
// Initialize the hover handler.
//
- (id)init
{
    if ([super init] == nil)
	return nil;
    
    popups = [[NSMutableArray alloc] init];
    cancelImage = [[NSImage imageNamed:@"cancel_48"] retain];
    rejectImage = [[NSImage imageNamed:@"dnd"] copy];
    [rejectImage setSize:NSMakeSize(48, 48)];
    infoImage = [[NSImage imageNamed:@"info_48"] retain];
    
    return self;
}


//
// Free memory used by this object.
//
- (void)dealloc
{
    int	i;
    
    for (i = 0; i < [popups count]; i++)
    {
	[[popups objectAtIndex:i] dismiss];
    }
    [popups autorelease];
    popups = nil;
    
    [cancelImage autorelease];
    cancelImage = nil;
    
    [rejectImage autorelease];
    rejectImage = nil;
    
    [infoImage autorelease];
    infoImage = nil;
    [infoURL autorelease];
    infoURL = nil;
    
    [super dealloc];
}


//
// Show a new popup for the given call.
//
- (void)showPopupForCall:(SSCall *)call
{
    NSMutableDictionary	*content;
    NSMutableString	*message;
    SSHover		*popup;


    //
    // Setup the content string.
    //
    message = [NSMutableString string];
    if (call.person != nil)
    {
	if ([call.person valueForKey:kPLTitleKey] != nil)
	    [message appendFormat:@"%@ ", [call.person valueForKey:kPLTitleKey]];
	[message appendFormat:@"%@ %@\n", [call.person valueForKey:kPLFirstNameKey], [call.person valueForKey:kPLLastNameKey]];
	[message appendFormat:@"%@", [BMSnomPhone formatPhoneNumber:[call.person valueForKey:kPLPhoneNumberKey]]];
	if ([call.person valueForKey:kPLPhoneLabelKey] != nil)
	    [message appendFormat:@" (%@)\n", [call.person valueForKey:kPLPhoneLabelKey]];
	else
	    [message appendString:@"\n"];
	if ([call.person valueForKey:kPLAddressStreetKey] != nil) {
	    [message appendFormat:@"%@\n%@ %@, %@\n",
	     [call.person valueForKey:kPLAddressStreetKey], [call.person valueForKey:kPLAddressCityKey],
	     [call.person valueForKey:kPLAddressStateKey], [call.person valueForKey:kPLAddressZIPKey]];
	}
        infoURL = [call.person valueForKey:kPLLinkKey];
    }
    else
    {
	[message appendFormat:@"Unknown Caller\n%@", [BMSnomPhone formatPhoneNumber:call.remoteNumber]];
    }
    
    if ([message characterAtIndex:([message length] - 1)] == '\n')
	[message replaceCharactersInRange:NSMakeRange([message length] - 1, 1) withString:@""];
    
    //
    // Create and show the actual hover notification.
    //
    content = [NSMutableDictionary dictionary];
    [content setValue:message forKey:kHoverPanelMessageKey];
    if ([[call.person valueForKey:kPLImageData] length] > 0)
	[content setValue:[[[NSImage alloc] initWithData:[call.person valueForKey:kPLImageData]] autorelease] forKey:kHoverPanelImageKey];
    [content setValue:[NSArray arrayWithObjects:cancelImage, rejectImage, (infoURL != nil ? infoImage : nil), nil] forKey:kHoverPanelButtonsKey];
    popup = [[[SSHover alloc] initWithContent:content notifyDelegate:self] autorelease];
    popup.visibleTime = [[[BMSnomPhone preferences] valueForKey:kPopupDurationKey] intValue];
    popup.context = call;
    [popups addObject:popup];
    [popup show];
}



#pragma mark SSHoverDelegate methods

//
// Popup has been dismissed, either by the user or a timeout.
//
- (void)popupNotificationDidDismiss:(SSHover *)popup
{
    [popup retain];
    [popups removeObjectIdenticalTo:popup];
    [popup autorelease];
}


//
// User clicked a button on the popup.
//
- (void)popupNotification:(SSHover *)popup didClickButton:(int)buttonIndex
{
    SSCall *call = popup.context;
    
    
    //
    // User wants to get rid of the alert screen.
    //
    if (buttonIndex == 0)
    {
	[popup dismiss];
    }
    
    //
    // User wants to send the call to voicemail.
    //
    if (buttonIndex == 1)
    {
	NSMutableURLRequest *request;
	NSString	    *content;
	
	content = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
		   "   <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"xmlns:csta=\"http://www.ecma-international.org/standards/ecma-323/csta/ed4\">\n"
		   "   <SOAP-ENV:Body>\n"
		   "   <csta:ClearCall>\n"
		   "   <csta:callToBeCleared>%@</csta:callToBeCleared>\n"
		   "   </csta:ClearCall>\n"
		   "   </SOAP-ENV:Body>\n"
		   "   </SOAP-ENV:Envelope>", call.callID];
	
	request = [NSMutableURLRequest requestWithURL:[[BMSnomPhone sharedPhone] buildPhoneURL:@"/csta"]];
	[request setHTTPMethod:@"POST"];
	[request setHTTPBody:[content dataUsingEncoding:NSUTF8StringEncoding]];
	[NSURLConnection connectionWithRequest:request delegate:nil];
	
	[popup dismiss];
    }
    
    //
    // User wants to follow the link supplied for the person.
    //
    if (buttonIndex == 2)
    {
        [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:infoURL]];
    }
}



#pragma mark BMPluginHandlerProtocol
//////////////////////////////////////////////////////////////////////////
//
// BMPluginHandlerProtocol
//
//////////////////////////////////////////////////////////////////////////


//
// Notification continues through all plugins until all plugins have been
// notified. The phoneNumber will never be nil while the person may be nil
// if no lookup found a match.
//
- (void)notifyIncomingCall:(SSCall *)call
{
    //
    // Only show a popup if we are active.
    //
    if ([[[BMSnomPhone preferences] valueForKey:kPopupIncomingEnabledKey] boolValue] == NO)
	return;

    [self showPopupForCall:call];
}


//
// Notification continues through all plugins until all plugins have been
// notified. The phoneNumber will never be nil while the person may be nil
// if no lookup found a match.
//
- (void)notifyOutgoingCall:(SSCall *)call
{
    //
    // Only show a popup if we are active.
    //
    if ([[[BMSnomPhone preferences] valueForKey:kPopupOutgoingEnabledKey] boolValue] == NO)
	return;
    
    [self showPopupForCall:call];
}


//
// Notification that the call has ended.
//
- (void)notifyCallEnded:(SSCall *)call
{
    SSHover *popup;
    int	    i;
    
    
    for (i = 0; i < [popups count]; i++)
    {
	popup = [popups objectAtIndex:i];
	if (popup.context == call)
	{
	    [popup dismiss];
	}
    }
}


@end
